package org.example.clouddemo.service.common.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;

import org.example.clouddemo.bean.common.entity.Order;
import org.example.clouddemo.bean.common.entity.Product;
import org.example.clouddemo.bean.common.entity.Stock;
import org.example.clouddemo.bean.common.param.CreateOrderParam;


import org.example.clouddemo.bean.common.param.PayParam;
import org.example.clouddemo.bean.common.param.StockParam;


import org.example.clouddemo.bean.common.vo.OrderVO;
import org.example.clouddemo.feign.PayFeignClient;
import org.example.clouddemo.feign.ProductFeignClient;

import org.example.clouddemo.feign.StockFeignClient;
import org.example.clouddemo.service.common.OrderService;
import org.example.clouddemo.service.common.mapper.OrderMapper;

import org.example.common.api.PaymentService;
import org.example.common.api.StockService;
import org.example.common.bean.LoginUser;
import org.example.common.exception.AppRunTimeException;
import org.example.common.response.ApiResult;
import org.example.common.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Log4j2
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    public StockFeignClient stockFeignClient;



    @Autowired
    public ProductFeignClient productFeignClient;

    @Autowired
    private OrderMapper orderMapper;




    @Autowired
    public PayFeignClient payFeignClient;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createOrder(CreateOrderParam param) {
        //获取产品信息

        Product find = new Product();
        find.setId(param.getProductId());
        ApiResult<Product> productApiResult = productFeignClient.getProductById(find);

        if (!productApiResult.isSuccess()) {
            throw new AppRunTimeException("找不到产品");
        }

        Product product = productApiResult.data;
        log.info("getProductById:{}", product);

        Product product2 = productFeignClient.getProductById2(find);

        log.info("getProductById2:{}", product2);

        // 获取用户信息
        LoginUser loginUser = SecurityUtils.getUserInfo();
        Long userId = loginUser.getId();

        // 1. 检查库存
        ApiResult<Stock> res = stockFeignClient.getOne(new StockParam(product.getId(),0));
       Stock stock = res.getData();
        if (stock == null || stock.getQuantity() < param.getQuantity()) {
            throw new RuntimeException("库存不足");
        }

        // 2. 计算订单金额
        BigDecimal orderAmount = product.getPrice().multiply(new BigDecimal(param.getQuantity()));

        // 3. 创建订单
        Order order = new Order();
        order.setId(IdUtil.getSnowflake().nextId());
        order.setUserId(userId);
        order.setProductId(param.getProductId());
        order.setQuantity(param.getQuantity());
        order.setAmount(orderAmount);
        order.setStatus(1); // 订单状态：1-待支付
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());

        // 4. 保存订单
        orderMapper.insert(order);

        // 5. 扣减库存
        stock.setQuantity(stock.getQuantity() - param.getQuantity());
        stockFeignClient.update(stock);


        // 异步调用支付模块
        asyncPay(order, orderAmount);
        return order.getId();
    }
    @Async("vodCallbackExecutor")
    @Transactional(rollbackFor = Exception.class)// 使用线程池异步执行
    public void asyncPay(Order order, BigDecimal amount) {
        try {

            payFeignClient.checkPayable(new PayParam(order, amount));

        } catch (Exception e) {
            log.error("支付失败: {}", e.getMessage());
        }
    }

    @Override
    public Page<List<OrderVO>> getOrderDetail(Page pageInfo) {


        LoginUser loginUser = SecurityUtils.getUserInfo();
        QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", loginUser.getId());
        queryWrapper.orderByDesc("create_time");
        Page<Order> page = orderMapper.selectPage(pageInfo, queryWrapper);
        List<Order> orders = page.getRecords();
        List<OrderVO> orderVOS = orders.stream().map(order -> {
            OrderVO orderVO = BeanUtil.copyProperties(order, OrderVO.class);
            Product product = new Product();
            product.setId(order.getProductId());
            ApiResult<Product> productById = productFeignClient.getProductById(product);
            Product product1 = productById.getData();
            orderVO.setProductName(product1.getProductName());
            orderVO.setProductImg(product1.getProductImg());
            return orderVO;
        }).collect(Collectors.toList());
        return pageInfo.setRecords(orderVOS);
    }

    @Override
    public boolean cancelOrder(Long orderId, LoginUser loginUser) {
        // 查询订单是否存在且属于当前用户
        Order order = orderMapper.selectById(orderId);
        if (order == null || !order.getUserId().equals(loginUser.getId())) {
            throw new AppRunTimeException("订单不存在或无权限操作");
        }

        // 更新订单状态为已取消（假设 status = 0 表示已取消）
        order.setStatus(0);
        int rows = orderMapper.updateById(order);
        ApiResult<Stock> result = stockFeignClient.getOne(new StockParam(order.getProductId(), 0));
        Stock stock = result.getData();
        stock.setQuantity(stock.getQuantity() + order.getQuantity());
        stockFeignClient.update(stock);
        return rows > 0;
    }

}